package HashMap;

import HashMap.Nodo.Nodo;
import java.util.LinkedList;
import java.util.List;

public final class Pila {

    private static Pila instancia = new Pila();
    private List<Tabla> pila = new LinkedList();
    private int contadorPila = 0;

    public Pila() {
    }

    public static Pila getInstancia() {
        return instancia;
    }

    public void addTabla() {
        pila.add(new Tabla());
        contadorPila = pila.size() - 1;
    }

    public void removeTabla() {
        int posicionElementoSuperiorPila = pila.size() - 1;
        if (posicionElementoSuperiorPila >= 0) {
            pila.remove(posicionElementoSuperiorPila);
        } else {
            throw new RuntimeException("La pila está vacía");
        }
        contadorPila = 1;
    }

    public Tabla getTablaCimaPila() {
        int posicionElementoSuperiorPila = contadorPila;
        if (posicionElementoSuperiorPila >= 0) {
            return pila.get(posicionElementoSuperiorPila);
        } else {
            throw new RuntimeException("La pila está vacía");
        }
    }

    public int getCantidadTablasApiladas() {
        return this.pila.size();
    }

    public void addNodoALaTablaSuperior(Nodo nodo) {
        getTablaCimaPila().addNodo(nodo);
    }

    public void addNodosALaTablaSuperior(Nodo nodo, List<String> nombres) {
        for (String nombreAux : nombres) {
            Nodo nodoAux = nodo.copiarNodo();
            nodoAux.setNombre(nombreAux);
            addNodoALaTablaSuperior(nodoAux);
        }
    }

    public boolean existeNodoEnLaPila(String nombreNodo) {
        for (int i = pila.size() - 1; i >= 0; i--) {
            if (pila.get(i).existeNodoEnLaTabla(nombreNodo)) {
                return true;
            }
        }
        return false;
    }

    public Nodo getPrimerNodoQueCoincida(String nombreNodo) {
        for (int i = pila.size() - 1; i >= 0; i--) {
            if (pila.get(i).existeNodoEnLaTabla(nombreNodo)) {
                return pila.get(i).getNodo(nombreNodo);
            }
        }
        throw new RuntimeException("No existe ningún nodo en la pila que coincida...");
    }

    public String generarCodigoNASMInicioPila() {
        StringBuilder builder = new StringBuilder();
        builder.append("segment .data\\n\\nsegment .bss\\n");
        for (Tabla tabla : pila) {
            builder.append(tabla.generarCodigoNASMVariables());
            builder.append("\n");
        }
        return builder.toString();
    }

    public String generarCodigoNASMFunciones() {
        StringBuilder builder = new StringBuilder();
        for (Tabla tabla : pila) {
            builder.append(tabla.generarCodigoNASMFunciones());
            builder.append("\n");
        }
        return builder.toString();
    }
}
